﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Text;
using DBUtil.MetaData;
using System.Linq;
using System.Collections.Concurrent;
using System.Threading;
using MySqlConnector;
using DBUtil.Provider.MySql.MetaData;
using DBUtil.Util;
using DotNetCommon.Data;
using Index = DBUtil.MetaData.Index;
using DotNetCommon.Extensions;

namespace DBUtil.Provider.MySql
{
    /// <summary>
    /// MySql操作对象
    /// </summary>
    public class MySqlManage : DBManage
    {
        /// <summary>
        /// 根据DBAccess创建DBManage
        /// </summary>
        /// <param name="db"></param>
        public MySqlManage(DBAccess db) : base(db) { }

        #region 获取元数据信息
        /// <summary>
        /// 返回所有的架构/模式
        /// </summary>
        /// <returns></returns>
        public override List<Schema> ShowSchemas()
        {
            var res = base.ShowSchemas();
            res.ForEach(schema => schema.DataBaseName = schema.Name);
            return res;
        }

        /// <summary>
        /// 是否给表填充详细信息,默认不填充,即只有表名称/表说明/创建/修改时间
        /// </summary>
        /// <returns></returns>
        public override List<Table> ShowTables(string schemaName, bool isDetail = false)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 返回指定表的详细元数据
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <param name="schemaName">模式名称</param>
        public override Table ShowTableDetail(string tableName, string schemaName = null)
        {
            return FillTableInfo(tableName);
        }

        /// <summary>
        /// 给表填充元数据信息
        /// </summary>
        /// <param name="tableName">表名称</param>
        private Table FillTableInfo(string tableName)
        {
            using (db.OpenLongConnectOnce())
            {
                var table = new MySqlTable() { Name = tableName };
                FillTableInfo(table);
                FillColumns(table);
                FillTriggers(table);
                FillConstraints(table);
                FillIndexes(table);
                return table;
            };
        }

        /// <summary>
        /// 根据表名填充表说明/创建时间/更新时间/架构
        /// </summary>
        /// <param name="table"></param>
        private void FillTableInfo(MySqlTable table)
        {
            if (table == null) return;
            string sql = $@"select * from information_schema.`TABLES` t where t.table_schema='{db.DataBase}' and t.TABLE_TYPE='BASE TABLE' and t.TABLE_NAME='{table.Name}'"; ;
            DataTable dt = db.SelectDataTable(sql);
            if (dt.Rows.Count > 0)
            {
                table.Name = dt.Rows[0]["TABLE_NAME"].ToString();
                table.Desc = dt.Rows[0]["TABLE_COMMENT"].ToString();
                table.CreateTime = DateTime.Parse(dt.Rows[0]["CREATE_TIME"].ToString());
                table.Engine = dt.Rows[0]["ENGINE"].ToString();
                var updatetime = dt.Rows[0]["UPDATE_TIME"].ToString();
                if (!string.IsNullOrWhiteSpace(updatetime))
                {
                    table.LastUpdate = DateTime.Parse(updatetime);
                }
                table.SchemaName = dt.Rows[0]["TABLE_SCHEMA"].ToString();
            }
        }

        /// <summary>
        /// 根据表名填充列信息
        /// </summary>
        /// <param name="table">要进行填充的表</param>
        private void FillColumns(Table table)
        {
            if (table == null) return;
            string sql = $@"select * from information_schema.COLUMNS T WHERE T.TABLE_SCHEMA='{db.DataBase}' and T.TABLE_NAME='{table.Name}'";
            DataTable dt = db.SelectDataTable(sql);
            List<Column> columns = new List<Column>();
            table.PrimaryKeyColumns = new List<Column>();
            if (dt.Rows.Count > 0)
            {
                for (int i = 0, len = dt.Rows.Count; i < len; i++)
                {
                    var column = new MySqlColumn();
                    column.Name = dt.Rows[i]["COLUMN_NAME"].ToString();
                    column.TableName = table.Name;
                    //列类型
                    column.TypeString = dt.Rows[i]["COLUMN_TYPE"].ToString();
                    //TODO 设置类别
                    //列说明
                    column.Desc = dt.Rows[i]["COLUMN_COMMENT"].ToString();
                    //是否可空
                    column.IsNullAble = dt.Rows[i]["IS_NULLABLE"].ToString() == "NO" ? false : true;
                    //自增
                    column.IsIdentity = dt.Rows[i]["EXTRA"].ToString() == "auto_increment" ? true : false;
                    if (column.IsIdentity)
                    {
                        //先设置为1,1
                        column.IdentityStart = 1;
                        column.IdentityIncre = 1;
                    }
                    //默认值
                    var de = dt.Rows[i]["COLUMN_DEFAULT"].ToString();
                    column.HasDefault = string.IsNullOrEmpty(de) ? false : true;
                    if (column.HasDefault) column.Default = de;
                    columns.Add(column);
                    //唯一:通过唯一约束修正
                    //主键
                    var columnkey = dt.Rows[i]["COLUMN_KEY"].ToString();
                    if (columnkey.Contains("PRI"))
                    {
                        table.PrimaryKeyColumns.Add(column);
                    }
                    if (columnkey.Contains("UNI"))
                    {
                        column.IsUnique = true;
                    }
                }
            }
            table.Columns = columns;
            if (table.PrimaryKeyColumns.Count > 0)
            {
                table.PrimaryKey = string.Join(",", table.PrimaryKeyColumns.Select(col => col.Name).ToList());
            };
        }

        /// <summary>
        /// 根据表名填充触发器信息
        /// </summary>
        /// <param name="table">要进行填充的表</param>
        private void FillTriggers(Table table)
        {
            table.Triggers = ShowTableTriggers(table.Name, table.SchemaName);
        }

        /// <summary>
        /// 根据表名填充约束信息
        /// </summary>
        /// <param name="table">要进行填充的表</param>
        private void FillConstraints(Table table)
        {
            table.Constraints = ShowTableConstraints(table.Name, table.SchemaName);
        }

        /// <summary>
        /// 根据表名称填充索引信息
        /// </summary>
        /// <param name="table"></param>
        private void FillIndexes(Table table)
        {
            table.Indexes = ShowTableIndexes(table.Name, table.SchemaName);
        }

        /// <summary>
        /// 返回所有的视图(仅用户创建的视图)
        /// </summary>
        /// <returns></returns>
        public override List<View> ShowViews(string schemaName = null)
        {
            List<View> views = new List<View>();
            if (schemaName.IsNullOrEmptyOrWhiteSpace()) schemaName = db.DataBase;
            var sql = $"select * from information_schema.views where table_schema='{db.DealSqlInject(schemaName)}'";
            var dt = db.SelectDataTable(sql);
            for (int i = 0, len = dt.Rows.Count; i < len; i++)
            {
                var name = dt.Rows[i]["TABLE_NAME"].ToString();
                var schema = dt.Rows[i]["TABLE_SCHEMA"].ToString();
                var view_definition = dt.Rows[i]["TABLE_SCHEMA"].ToString();
                var view = new MySqlView()
                {
                    Name = name,
                    SchemaName = schema,
                    VIEW_DEFINITION = view_definition,
                    DEFINER = dt.Rows[i]["DEFINER"].ToString(),
                    SECURITY_TYPE = dt.Rows[i]["SECURITY_TYPE"].ToString(),
                    CHECK_OPTION = dt.Rows[i]["CHECK_OPTION"].ToString()
                };
                view.CreateSql = $"create view `{schema}`.`{name}` as\r\n{view_definition}";
                views.Add(view);
            }
            return views;
        }

        /// <summary>
        /// 返回所有的存储过程(仅用户自定义的)
        /// </summary>
        /// <returns></returns>
        public override List<Procedure> ShowProcedures(string schemaName = null)
        {
            if (schemaName.IsNullOrEmptyOrWhiteSpace()) schemaName = db.DataBase;
            List<Procedure> res = new List<Procedure>();
            string sql = $@"select * from INFORMATION_SCHEMA.ROUTINES
where ROUTINE_TYPE='PROCEDURE' and ROUTINE_SCHEMA='{db.DealSqlInject(schemaName)}'";
            DataTable dt = db.SelectDataTable(sql);
            if (dt.Rows.Count > 0)
            {
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    var proc = new MySqlProcedure();
                    proc.Name = dt.Rows[i]["ROUTINE_NAME"].ToString();
                    proc.CreateTime = DateTime.Parse(dt.Rows[i]["CREATED"].ToString());
                    var lastupdate = dt.Rows[i]["LAST_ALTERED"].ToString();
                    if (!string.IsNullOrWhiteSpace(lastupdate))
                    {
                        proc.LastUpdate = DateTime.Parse(lastupdate);
                    }
                    proc.CreateSql = dt.Rows[i]["ROUTINE_DEFINITION"].ToString();
                    proc.SchemaName = db.DataBase;
                    sql = $"show create PROCEDURE {proc.Name}";
                    var tt = db.SelectDataTable(sql);
                    proc.CreateSql = tt.Rows[0]["Create Procedure"].ToString();
                    res.Add(proc);
                }
            }
            return res;
        }

        /// <summary>
        /// 返回指定表的所有约束(mysql中只能查到主键、检查、唯一约束)
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <param name="schemaName"></param>
        /// <returns></returns>
        public override List<DBUtil.MetaData.Constraint> ShowTableConstraints(string tableName, string schemaName)
        {
            var table = new MySql.MetaData.MySqlTable()
            {
                Name = tableName
            };
            FillColumns(table);
            List<DBUtil.MetaData.Constraint> constraints = new List<DBUtil.MetaData.Constraint>();
            string sql = $"select * from information_schema.TABLE_CONSTRAINTS where table_schema='{db.DataBase}' and TABLE_NAME='{tableName}'";
            var dt = db.SelectDataTable(sql);
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                var constraint = new MySqlConstraint();
                constraint.TableName = tableName;
                constraint.Name = dt.Rows[i]["CONSTRAINT_NAME"].ToString();
                constraints.Add(constraint);
                var constraint_schema = dt.Rows[i]["CONSTRAINT_SCHEMA"].ToString();
                string type = (dt.Rows[i]["constraint_type"] ?? "").ToString();
                if (type.StartsWith("CHECK"))
                {
                    constraint.Type = EnumConstraintType.Check;
                    sql = $"select CHECK_CLAUSE from information_schema.CHECK_CONSTRAINTS where CONSTRAINT_NAME='{constraint.Name}' and CONSTRAINT_SCHEMA='{constraint_schema}'";
                    constraint.Content = db.SelectScalar<string>(sql);
                }
                else if (type.StartsWith("PRIMARY"))
                {
                    constraint.Type = EnumConstraintType.PrimaryKey;
                    constraint.Constraintkeys = table.PrimaryKey;
                }
                else if (type.StartsWith("UNIQUE"))
                {
                    constraint.Type = EnumConstraintType.Unique;
                    constraint.Constraintkeys = constraint.Name;
                }
            }
            return constraints;
        }
        /// <summary>
        /// 返回指定表所有索引
        /// </summary>
        /// <param name="tableName">所属的表名称</param>
        /// <param name="schemaName">模式名称</param>
        /// <returns></returns>
        public override List<Index> ShowTableIndexes(string tableName, string schemaName)
        {
            List<Index> indexs = new List<Index>();
            if (string.IsNullOrWhiteSpace(tableName)) return indexs;
            string sql = $"show INDEX from {tableName}";
            var dt = db.SelectDataTable(sql);
            if (dt != null && dt.Rows.Count > 0)
            {
                var lastindexname = string.Empty;
                for (int i = dt.Rows.Count - 1; i >= 0; i--)
                {
                    var index = new MySqlIndex();
                    index.TableName = tableName;
                    index.Name = dt.Rows[i]["Key_name"].ToString();
                    string colname = dt.Rows[i]["Column_name"].ToString();
                    if (lastindexname == index.Name)
                    {
                        indexs[indexs.Count - 1].ColumnNames += colname;
                        continue;
                    }
                    lastindexname = index.Name;
                    index.ColumnNames += "," + colname;
                    index.Desc = dt.Rows[i]["Index_comment"].ToString();
                    //认为主键是聚集索引,其他的为非聚集索引
                    if (index.Name == "PRIMARY")
                    {
                        index.IsClustered = true;
                    }
                    else
                    {
                        index.IsClustered = false;
                    }
                    index.IndexType = dt.Rows[i]["Index_type"].ToString();
                    indexs.Add(index);
                }
            }
            return indexs;
        }
        #endregion

        #region 修改元数据
        /// <summary>
        /// 重命名表名
        /// </summary>
        /// <param name="oldName">旧表名</param>
        /// <param name="newName">新表名</param>
        /// <param name="schemaName">指定模式名</param>
        /// <returns></returns>
        public override Result RenameTable(string oldName, string newName, string schemaName = null)
        {
            oldName = db.QuoteIdentifierWithDefaultSchema(oldName, schemaName);
            newName = db.QuoteIdentifierWithDefaultSchema(newName, schemaName);
            return Result.Wrap(() =>
            {
                string sql = $"RENAME table {oldName} to {newName}";
                db.ExecuteSql(sql);
            });
        }

        /// <summary>
        /// 重命名列名
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <param name="oldName">旧列名</param>
        /// <param name="newName">新列名</param>
        /// <param name="schemaName">指定schema名称</param>
        /// <returns></returns>
        public override Result RenameColumn(string tableName, string oldName, string newName, string schemaName = null)
        {
            return Result.Wrap(() =>
            {
                using (db.OpenLongConnectOnce())
                {
                    var table = new MySqlTable() { Name = tableName };
                    FillColumns(table);
                    var column = table.Columns.Where(col => col.Name.ToUpper() == oldName.ToUpper()).FirstOrDefault();
                    column.Name = newName;
                    var sql = GetModifyColumnSql(column);
                    sql = sql.Replace("modify column", $"change {oldName}");
                    db.ExecuteSql(sql);
                };
            });
        }

        /// <summary>
        /// 修改表说明
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <param name="desc">说明信息</param>
        /// <param name="schemaName">指定schema名称</param>
        public override Result UpdateTableDescription(string tableName, string desc, string schemaName = null)
        {
            return Result.Wrap(() =>
            {
                string sql = $"alter table {tableName} comment '{desc}';";
                db.ExecuteSql(sql);
            });
        }

        /// <summary>
        /// 删除指定表
        /// </summary>
        /// <param name="tableName">要删除的表</param>
        /// <param name="schemaName">指定schema名称</param>
        /// <returns></returns>
        public override Result DropTable(string tableName, string schemaName = null)
        {
            return Result.Wrap(() =>
            {
                string sql = $"DROP TABLE {tableName}";
                db.ExecuteSql(sql);
            });
        }

        /// <summary>
        /// 删除指定表,如果存在
        /// </summary>
        /// <param name="tableName"></param>
        /// <param name="schemaName">指定schema名称</param>
        /// <returns></returns>
        public override Result DropTableIfExist(string tableName, string schemaName = null)
        {
            return Result.Wrap(() =>
            {
                string sql = $"DROP TABLE IF EXISTS {tableName}";
                db.ExecuteSql(sql);
            });
        }

        /// <summary>
        /// 修改列说明
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <param name="colName">列名</param>
        /// <param name="desc">说明信息</param>
        /// <param name="schemaName">指定schema名称</param>
        public override Result UpdateColumnDescription(string tableName, string colName, string desc, string schemaName = null)
        {
            return Result.Wrap(() =>
            {
                using (db.OpenLongConnectOnce())
                {
                    var table = new MySqlTable() { Name = tableName };
                    FillColumns(table);
                    var column = table.Columns.Where(col => col.Name.ToUpper() == colName?.ToUpper()).FirstOrDefault();
                    if (column == null) throw new Exception($"没有找到列{colName}");
                    column.Desc = desc;
                    var sql = GetModifyColumnSql(column);
                    db.ExecuteSql(sql);
                };
            });
        }

        /// <summary>
        /// 获取列修改语句
        /// </summary>
        /// <param name="column">列模型</param>
        /// <returns></returns>
        public string GetModifyColumnSql(Column column)
        {
            if (column == null) return string.Empty;
            string sql = $"alter table {column.TableName} modify column {column.Name} {column.TypeString}";
            if (column.IsIdentity)
            {
                sql += " auto_increment";
            }
            if (column.IsPrimaryKey)
            {
                sql += " primary key";
            }
            if (!column.IsNullAble)
            {
                sql += " not null";
            }
            if (column.HasDefault)
            {
                sql += $" default('{column.Default}')";
            }
            if (column.IsUnique)
            {
                sql += " unique";
            }
            return sql;
        }

        /// <summary>
        /// 删除指定表的指定列
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <param name="columnName">要删除的列名</param>
        /// <param name="schemaName">指定schema名称</param>
        /// <returns></returns>
        public override Result DropColumn(string tableName, string columnName, string schemaName = null)
        {
            return Result.Wrap(() =>
            {
                string sql = $"ALTER TABLE {tableName} DROP {columnName}";
                db.ExecuteSql(sql);
            });
        }

        /// <summary>
        /// 获取列定义数据
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <param name="colName">列名</param>
        /// <returns></returns>
        public Column GetColumn(string tableName, string colName)
        {
            if (string.IsNullOrWhiteSpace(tableName)) return null;
            var table = new MySqlTable() { Name = tableName };
            FillColumns(table);
            return table.Columns.Where(col => col.Name.ToUpper() == colName?.ToUpper()).FirstOrDefault();
        }

        /// <summary>
        /// 修改指定表的指定列是否可以为空
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <param name="columnName">列名</param>
        /// <param name="canNull">是否可空</param>
        /// <param name="columnType">列类型,如果columnType为空,程序会自动探索列类型</param>
        /// <returns></returns>
        public Result AlterColumnNullAble(string tableName, string columnName, bool canNull, string columnType)
        {
            return ModifyColumn(tableName, columnName, col => { col.TypeString = string.IsNullOrWhiteSpace(columnType) ? col.TypeString : columnType; col.IsNullAble = canNull; });
        }

        /// <summary>
        /// 给指定列修改默认值
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <param name="columnName">列名</param>
        /// <param name="def">默认值</param>
        /// <returns></returns>
        public Result AlterColumnDefault(string tableName, string columnName, string def)
        {
            return ModifyColumn(tableName, columnName, col => { col.HasDefault = true; col.Default = def; });
        }

        /// <summary>
        /// 修改列属性
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <param name="columnName">列名</param>
        /// <param name="action">修改逻辑</param>
        /// <returns></returns>
        public Result ModifyColumn(string tableName, string columnName, Action<Column> action)
        {
            if (action == null) return Result.Ok();
            return Result.Wrap(() =>
            {
                using (db.OpenLongConnectOnce())
                {
                    Column column = GetColumn(tableName, columnName);
                    if (column == null) throw new Exception($"未找到列:{columnName}");
                    action(column);
                    var sql = GetModifyColumnSql(column);
                    db.ExecuteSql(sql);
                };
            });
        }

        /// <summary>
        /// 删除指定表指定列的默认值
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <param name="columnName">列名</param>
        /// <returns></returns>
        public Result DropColumnDefault(string tableName, string columnName)
        {
            return ModifyColumn(tableName, columnName, col => col.HasDefault = false);
        }

        /// <summary>
        /// 给指定表添加一列
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <param name="column">列</param>
        /// <param name="schemaName">指定schema名称</param>
        /// <returns></returns>
        public override Result AddColumn(string tableName, Column column, string schemaName = null)
        {
            if (column == null) return Result.NotOk("必须指定列属性!");
            if (string.IsNullOrWhiteSpace(column.TableName))
            {
                column.TableName = tableName;
            }
            if (string.IsNullOrWhiteSpace(column.TableName)) return Result.NotOk("必须指定表名称");
            string sql = GetModifyColumnSql(column);
            sql = sql.Replace(" modify ", " add ");
            return Result.Wrap(() =>
            {
                db.ExecuteSql(sql);
            });

        }

        /// <summary>
        /// 设置指定列是否是唯一的
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <param name="columnName">列名,可以是多个列,如:"Name,Age"</param>
        /// <param name="canUnique">是否是唯一的</param>
        public Result AlterColumnUnique(string tableName, string columnName, bool canUnique)
        {
            if (string.IsNullOrWhiteSpace(tableName) || string.IsNullOrWhiteSpace(columnName))
            {
                return Result.NotOk("表名或列名不能为空!");
            }
            var arr = columnName.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            var sql = $"alter table {tableName} add constraint unique_{tableName}_{string.Join("_", arr)} unique({string.Join(",", arr)});";
            return Result.Wrap(() =>
            {
                db.ExecuteSql(sql);
            });
        }

        /// <summary>
        /// 创建表,注意创建的内容有:表和列说明/列类型/列自增/列的非空/列的唯一/列的默认值/主键
        /// </summary>
        /// <param name="table">表结构</param>
        public override Result CreateTable(Table table)
        {
            if (table == null) return Result.NotOk("必须指定表属性!");
            //最终create语句
            string sql = $@"create table `{table.Name}` (
";
            //主键列名称,如:name,age
            string priname = "";
            //主键名称,如:name_age
            string prikey = "";
            //表说明以及列说明语句
            string sqltabledesc = "";
            if (!string.IsNullOrWhiteSpace(table.Desc))
            {
                //给表加说明
                sqltabledesc += $" comment '{table.Desc}'";
            }
            table.Columns.ForEach(i =>
            {
                string ideSql = "";
                string nullSql = "";
                string defSql = "";
                string uniSql = "";
                string descSql = "";
                if (i.IsIdentity)
                {
                    ideSql = " auto_increment";
                }
                if (i.IsUnique)
                {
                    uniSql = " unique";
                }
                if (!i.IsNullAble)
                {
                    nullSql = " not null";
                }
                if (!string.IsNullOrWhiteSpace(i.Default))
                {
                    defSql = " default ('" + i.Default + "')";
                }
                if (i.IsPrimaryKey)
                {
                    priname += "_" + i.Name;
                    prikey += "," + i.Name;
                }
                if (!string.IsNullOrWhiteSpace(i.Desc))
                {
                    descSql += $" comment '{i.Desc}'";
                }

                sql += string.Format(@" [{0}] {1} {2} {3} {4} {5} {6},
", i.Name, i.TypeString, nullSql, defSql, ideSql, uniSql, descSql);
            });
            priname = priname.Trim('_');
            prikey = prikey.Trim(',');
            if (prikey.Contains(","))
            {
                string[] arr = prikey.Split(',');
                prikey = "";
                for (int i = 0; i < arr.Length; i++)
                {
                    prikey += "`" + arr[i] + "`,";
                }
                prikey = prikey.Trim(',');
            }
            string sqlPri = $@"
ALTER TABLE [{table.Name}] ADD CONSTRAINT PK_gene_{table.Name}_{priname} PRIMARY KEY({prikey})";
            if (prikey == "")
            {
                sqlPri = "";
            }
            sql += $@"
) {sqltabledesc};
";
            return Result.Wrap(() =>
            {
                using (db.OpenLongConnectOnce())
                {
                    db.ExecuteSql(sql);
                    db.ExecuteSql(sqlPri);
                };
            });
        }

        /// <summary>
        /// 返回触发器集合
        /// </summary>
        /// <param name="tableName">所属的表名称</param>
        /// <param name="schemaName"></param>
        /// <returns></returns>
        public override List<Trigger> ShowTableTriggers(string tableName, string schemaName)
        {
            if (string.IsNullOrWhiteSpace(tableName)) return new List<Trigger>();
            List<Trigger> triggers = new List<Trigger>();
            string sql = $"select * from information_schema.`TRIGGERS` where EVENT_OBJECT_SCHEMA='{db.DataBase}' and EVENT_OBJECT_TABLE='{tableName}'";
            DataTable dt = db.SelectDataTable(sql);
            for (int i = 0, len = dt.Rows.Count; i < len; i++)
            {
                string name = dt.Rows[i]["TRIGGER_NAME"].ToString();
                var condition = dt.Rows[i]["EVENT_MANIPULATION"].ToString().ToUpper();
                bool isUpdate = condition == "UPDATE";
                bool isDelete = condition == "DELETE";
                bool isInsert = condition == "INSERT";
                bool isAfter = dt.Rows[i]["ACTION_TIMING"].ToString() == "AFTER" ? false : true;
                var createtime = DateTime.Parse(dt.Rows[i]["CREATED"].ToString());
                bool isinsteadof = false;
                sql = $"show create trigger {name}";
                DataTable dt2 = db.SelectDataTable(sql);
                string createSql = dt2.Rows[0]["SQL Original Statement"].ToString();
                Trigger tri = new MySqlTrigger()
                {
                    Name = name,
                    CreateSql = createSql,
                    TableName = tableName,
                    IsInsert = isInsert,
                    IsUpdate = isUpdate,
                    IsDelete = isDelete,
                    IsAfter = isAfter,
                    IsInsteadof = isinsteadof,
                    CreateTime = createtime
                };
                triggers.Add(tri);
            }
            return triggers;
        }
        #endregion

        #region 生成insert语句 暂未实现
        /// <summary>
        /// 返回指定表的所有列
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <param name="schemaName">模式名称</param>
        /// <returns></returns>
        public override List<Column> ShowTableColumns(string tableName, string schemaName)
        {
            throw new NotImplementedException();
        }

        public override List<Function> ShowFunctions(string schemaName = null)
        {
            throw new NotImplementedException();
        }

        public override List<Sequence> ShowSequences(string schemaName = null)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// truncate指定表
        /// </summary>
        /// <param name="schemaName">模式名</param>
        /// <param name="tableName">表名</param>
        public override void TruncateTable(string tableName, string schemaName)
        {
            (tableName, schemaName) = db.AnalysisIdentifierWithDefaultSchema(tableName, schemaName);
            if (!schemaName.IsNullOrEmptyOrWhiteSpace()) tableName = $"`{schemaName}`.`{tableName}`";
            else tableName = $"`{tableName}`";
            db.ExecuteSql($"truncate table {tableName}");
        }

        public override Result DropTriggerIfExist(string triggerName, string schemaName = null)
        {
            throw new NotImplementedException();
        }

        public override Result DropProcedureIfExist(string procedureName, string schemaName = null)
        {
            return Result.Wrap(() =>
            {
                if (db.JudgeProcedureExist(procedureName)) db.Manage.DropProcedure(procedureName);
            });
        }

        public override View ShowViewDetail(string viewName, string schemaName)
        {
            throw new NotImplementedException();
        }

        public override Result UpdateViewDescription(string viewName, string desc, string schemaName = null)
        {
            throw new NotImplementedException();
        }

        public override (long count, string sql, long total) GenerateInsertSql(string schemaName, string tableName, int limitCount = 0, string filter = null, params IDataParameter[] paras)
        {
            throw new NotImplementedException();
        }

        public override long GenerateInsertSqlFile(string schemaName, string tableName, string fileAbsPath, int limitCount = 0, string filter = null, params IDataParameter[] paras)
        {
            throw new NotImplementedException();
        }

        public override long GetCount(string tableName, string schemaName = null)
        {
            throw new NotImplementedException();
        }

        public override string GenerateCreateTableSql(string tableName, string shemaName)
        {
            throw new NotImplementedException();
        }

        public override void GenerateCreateTableSqlFile(List<Table> tables, string fileAbsPath, bool includeInsertSql = false)
        {
            throw new NotImplementedException();
        }

        public override string GenerateCode(string tableName, string shemaName)
        {
            throw new NotImplementedException();
        }
        #endregion
    }
}
